/*
 * @(#)CharmPlayRule.java $version 2013. 7. 10.
 *
 */

package com.pace.gonu.model.rule;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.util.CollectionUtils;

import com.pace.gonu.constants.CharmBoardGroup;
import com.pace.gonu.constants.CharmBoardXY;
import com.pace.gonu.constants.Order;
import com.pace.gonu.constants.Status;
import com.pace.gonu.model.BoardPath;
import com.pace.gonu.model.PlayRock;
import com.pace.gonu.model.status.PlayStatus;

/**
 * @author pace
 */
public class CharmPlayRule implements PlayRule {
	private List<PointWithDestination> doMovePathList = new ArrayList<PointWithDestination>();
	private Integer[][] movePathList = { {2, 4, 10}, {1, 3, 5}, {2, 6, 15}, {1, 5, 7, 11}, {2, 4, 6, 8}, {3, 5, 9, 14}, {4, 8, 12}, {5, 7, 9},
		{6, 8, 13}, {1, 11, 22}, {4, 10, 12, 19}, {7, 11, 16}, {9, 14, 18}, {6, 13, 15, 21}, {3, 14, 24}, {12, 17, 19}, {16, 18, 20}, {13, 17, 21},
		{11, 16, 20, 22}, {17, 19, 21, 23}, {14, 18, 20, 24}, {10, 19, 23}, {20, 22, 24}, {15, 21, 23}};
	private int MAX_PLAY_ROCK = 24;

	public CharmPlayRule() {
		for (Integer[] movePath : movePathList) {
			List<Integer> destination = new ArrayList<Integer>();
			destination.addAll(Arrays.asList(movePath));
			setMovePathForPosition(destination);
		}
	}

	private void setMovePathForPosition(List<Integer> destination) {
		PointWithDestination doMovePath1 = new PointWithDestination();
		doMovePath1.setPoints(doMovePathList.size() + 1);
		doMovePath1.setDestinations(destination);
		doMovePathList.add(doMovePath1);
	}

	@Override
	public List<BoardPath> getMovePath(List<PlayRock> playRocks, PlayRock moveRock) {
		List<BoardPath> boardPaths = new ArrayList<BoardPath>();

		int boardPathIndex = CharmBoardXY.getPoint(moveRock);
		List<Integer> destinationList = doMovePathList.get(boardPathIndex).getDestinations();
		for (Integer destination : destinationList) {
			if (moveRock.getInitPathIndex() == destination) {
				continue;
			}

			BoardPath boardPath = new BoardPath();
			CharmBoardXY boardXY = CharmBoardXY.values()[destination - 1];

			if (!isPlayRockPath(playRocks, boardXY)) {
				boardPath.setX(boardXY.getX());
				boardPath.setY(boardXY.getY());
				boardPaths.add(boardPath);
			}
		}

		return boardPaths;
	}

	private boolean isPlayRockPath(List<PlayRock> playRocks, CharmBoardXY boardXY) {
		for (PlayRock playRock : playRocks) {
			if (playRock.getPath().getX() == boardXY.getX() && playRock.getPath().getY() == boardXY.getY()) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean isEndGame(PlayStatus playStatus, Order order) {
		if (!Status.MOVE.toString().equals(playStatus.getStatusType())) {
			return false;
		}
		
		if (playStatus.getPlayRocks().size() == MAX_PLAY_ROCK) {
			return true;
		}

		int playRockCnt = 0;
		List<PlayRock> playRocks = playStatus.getPlayRocks();
		
		for(PlayRock playRock:playRocks) {
			if (playRock.getOrderObject().equals(order)) {
				playRockCnt++;
			}
		}

		if (playRockCnt < 3) {
			return true;
		}

		return false;
	}
	
	@Override
	public boolean isCharm(List<PlayRock> playRocks, PlayRock playRock) {
		List<CharmBoardGroup> charmBoardGroups = CharmBoardGroup.getIncludeGroup(playRock.getPath().getX(), playRock.getPath().getY());
		for (CharmBoardGroup charmBoardGroup : charmBoardGroups) {
			List<CharmBoardXY> charmBoardXYs = charmBoardGroup.getListValues();

			/**
			 *  charmBoardGroup에 속하는 3개의 경로에 속하는 돌이 playRocks에 존재하는지 확인 
			 */
			int result = 0;
			for (CharmBoardXY charmBoardXY : charmBoardXYs) {
				for (PlayRock rock : playRocks) {
					if (!playRock.getOrderObject().equals(rock.getOrderObject())) {
						continue;
					}

					if (charmBoardXY.getX() == rock.getPath().getX() && charmBoardXY.getY() == rock.getPath().getY()) {
						result++;
					}
				}
			}

			if (result == 3) {
				return true;	
			}
		}
		return false;
	}

	@Override
	public boolean isMove(PlayStatus playStatus) {
		if (CollectionUtils.isEmpty(playStatus.getMoveRocks())) {
			return true;
		}
		return false;
	}
}
